package apitemplate

import (
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"time"

	"github.com/gin-gonic/gin"
	"gopkg.in/ini.v1"
)

var errMsgMap = make(map[string]map[string]string)

func init() {

	excusable, err := os.Executable()

	if err != nil {
		fmt.Printf("獲取執行路徑失敗: %v\n", err)
	}

	configPath := filepath.Join(filepath.Dir(excusable), "config/error-msg-i18n.ini")
	cfg, err := ini.Load(configPath)
	if err != nil {
		fmt.Printf("加載錯誤訊息配置文件失敗: %v\n", err)
	}

	for _, section := range cfg.Sections() {
		errCode := section.Name()
		errMsgMap[errCode] = make(map[string]string)
		for _, key := range section.Keys() {
			errMsgMap[errCode][key.Name()] = key.Value()
		}
	}

	fmt.Printf("加載錯誤訊息配置文件成功\n")
	fmt.Printf("%v\n", errMsgMap)
}

type BaseController struct {
	LangProfileReader LangProfileReader
}

func (b BaseController) Success(ctx *gin.Context, data interface{}) {
	ctx.JSON(http.StatusOK, RestResponseTemplate{
		ResultCode: StatusSuccess,
		ResultMsg:  "success",
		Data:       data,
		SysTime:    time.Now().UnixMilli(),
	})
}

func (b BaseController) Fail(ctx *gin.Context, err error) {

	errorMsg := b.GetErrI18nMsg(ctx, err)

	ctx.JSON(http.StatusOK, RestResponseTemplate{
		ResultCode: StatusFail,
		ResultMsg:  errorMsg,
		SysTime:    time.Now().UnixMilli(),
	})
}

func (b BaseController) GetErrI18nMsg(ctx *gin.Context, err error) string {

	if b.LangProfileReader == nil {
		b.LangProfileReader = DefaultLangProfileReader{}
	}
	var langType = b.LangProfileReader.GetLangProfile(ctx)

	if errMsg := errMsgMap[err.Error()]; errMsg != nil {
		if msg := errMsg[langType]; len(msg) > 0 {
			return msg
		}
	}

	return err.Error()
}

func (b BaseController) ReadLangWithHeader(ctx *gin.Context) string {
	return ctx.GetHeader("lang")
}

type LangProfileReader interface {
	GetLangProfile(ctx *gin.Context) string
}

type DefaultLangProfileReader struct {
}

func (b DefaultLangProfileReader) GetLangProfile(ctx *gin.Context) string {
	return ctx.GetHeader("lang")
}

const (
	StatusSuccess string = "1"
	StatusFail    string = "0"
)

type RestResponseTemplate struct {
	ResultCode string      `json:"result_code"`
	ResultMsg  string      `json:"result_msg"`
	Data       interface{} `json:"data"`
	SysTime    int64       `json:"sys_time"`
}
